package com.nave.segundaguerra.activity.views;

import java.util.Iterator;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;

import Enums.Zoom;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Point;
import android.graphics.PointF;
import android.graphics.Region;
import android.graphics.drawable.BitmapDrawable;
import android.support.v4.view.ViewPager.LayoutParams;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.RelativeLayout;
import android.widget.ZoomControls;

import com.example.honraepodercliente.R;
import com.nave.segundaguerra.activity.ConnectionSet;
import com.nave.segundaguerra.activity.GameInformation;
import com.nave.segundaguerra.game.CalculoImagem;
import com.nave.segundaguerra.game.Lupa;
import com.nave.segundaguerra.servidorecliente.cliente.ControleDeUsuarioCliente;
import com.nave.segundaguerra.servidorecliente.cliente.DadosDoCliente;
import com.nave.segundaguerra.servidorecliente.cliente.GeneralCliente;
import com.nave.segundaguerra.servidorecliente.cliente.ItemCliente;
import com.nave.segundaguerra.servidorecliente.cliente.MapaCliente;
import com.nave.segundaguerra.servidorecliente.cliente.MedicoCliente;
import com.nave.segundaguerra.servidorecliente.cliente.PlayerCliente;
import com.nave.segundaguerra.servidorecliente.cliente.SoldadoCliente;
import com.nave.segundaguerra.servidorecliente.cliente.TiroCliente;
import com.nave.segundaguerra.servidorecliente.cliente.ViewPort;
import com.nave.segundaguerra.servidorecliente.servidor.PlayerServer;
import com.nave.segundaguerra.servidorecliente.servidor.TiroServer;
import com.nave.segundaguerra.servidorecliente.util.ActivityUtil;
import com.nave.segundaguerra.servidorecliente.util.BitmapStorage;
import com.nave.segundaguerra.servidorecliente.util.Connection;
import com.nave.segundaguerra.servidorecliente.util.Const;
import com.nave.segundaguerra.servidorecliente.util.ElMatador;
import com.nave.segundaguerra.servidorecliente.util.ImageLibrary;
import com.nave.segundaguerra.servidorecliente.util.Killable;
import com.nave.segundaguerra.servidorecliente.util.RectLibrary;


public class GameView extends View implements Runnable, Killable {

	private final String TAG = "Game View";

	// Propriedades View
	private RelativeLayout container;
	private Point valueContainer;
	
	private Paint paint;
	private int fontSize = 0;
	
	private long interval = 10;
	private Bitmap bg;

	private int canvasWidth = 0;
	private int canvasHeight = 0;

	float scale = 1;
	
	// Servidor e Cliente
	private ControleDeUsuarioCliente clientManagerData;
	PlayerCliente meuJogador;
	private boolean ativo = true;
	
	// Interface
	Lupa lupa;
	Zoom MODE_ZOOM = Zoom.ZoomIN;

	public GameView(Context context, Connection connection,
			RelativeLayout container) {
		super(context);
		// #### Setando propriedades ####
		ElMatador.getInstance().add(this);

		this.container = container;
		this.clientManagerData = (ControleDeUsuarioCliente) connection.getHandler();
		//this.clientManagerData.playGame();
		//this.bg = ImageLibrary.getInstance().getImage("Cenario");
		//this.setBackgroundResource(R.drawable.cenario);
		paint = new Paint();
		paint.setColor(Color.BLACK);
		//paint.setTextSize(fontSize);

		// #### Carregando assets ####
		this.bg = BitmapStorage.getInstance().getCenario();
		ImageLibrary.getInstance().LoadAssetsGame(context);	
		

		// #### Enviando DadosIniciais ####
		//meuJogador = new SoldadoCliente(GameInformation.getNamePlayer(), new PointF(400,300));
		meuJogador = GameInformation.selecionarPlayerCliente(GameInformation.getClasse(), GameInformation.getNamePlayer(), new PointF(400,300));
		meuJogador.setTime(GameInformation.getTime());
		Log.i("#####DadosIniciais####", "Enviando Dados Iniciais !");
		meuJogador.setDadosCliente(new DadosDoCliente(connection, 30));
		
		Thread threadDados = new Thread(meuJogador.getDadosCliente());
		threadDados.start();
		
		meuJogador.sendDadosIniciais();
		// Send a message to server
		// Indicate this player how a new player in the game

		Thread thread = new Thread(this);
		thread.start();

	}

	protected void onSizeChanged(int w, int h, int oldw, int oldh) {

		Log.i(TAG, "OnSizeChanged w: " + w);
		Log.i(TAG, "OnSizeChanged h: " + h);
		Log.i(TAG, "OnSizeChanged old w: " + oldw);
		Log.i(TAG, "OnSizeChanged old h: " + oldh);

		this.canvasWidth = w;
		this.canvasHeight = h;
	}
	protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
		setMeasuredDimension(bg.getWidth(), bg.getHeight());
	}

	public void run() {
		while (ativo) {
			try {
				Thread.sleep(this.interval);
			} catch (InterruptedException e) {
				Log.i(TAG, "interrupcao do run()");
			}
			update();
			postInvalidate();
		}
	}

	int currentX = 0;
	int currentY = 0;
	int currentX2 = 0;
	int currentY2 = 0;
	
	int tamCanvasWidth;
	int tamCanvasHeight;
	
	public boolean onTouchEvent(MotionEvent event) {

		switch (event.getAction()) {

		case MotionEvent.ACTION_DOWN: {
			switch (MODE_ZOOM) {
			case ZoomIN:
				currentX = (int) event.getRawX();
				currentY = (int) event.getRawY();
				currentX += container.getScrollX();
				currentY += container.getScrollY();
				
				meuJogador.sendPos(new PointF(currentX,currentY));
				if(this.meuJogador.getMinhaClasse().equals("General")){
					//this.meuJogador.setStartLocation(new PointF(currentX,currentY));
					this.meuJogador.sendTiro(new Point(currentX,currentY));
					Log.i("Log","aqui1");
				}
				else{
					//meuJogador.sendTiro(new Point(currentX,currentY));
					this.meuJogador.sendNewTiro(new Point(currentX,currentY));
				}
				break;

			default:
				currentX2 = (int) event.getRawX();
				currentY2 = (int) event.getRawY();
				currentX2 += container.getScrollX();
				currentY2 += container.getScrollY();
				break;
			}

			if(!this.meuJogador.getMinhaClasse().equals("General")){
				meuJogador.dirViewPort(new Point(currentX,currentY), new Point(0, 0), new Point(this.tamCanvasWidth, this.tamCanvasHeight), this.container, scale);
			}

			if(this.lupa != null){
				if(this.lupa.Intersect(new PointF(event.getRawX() + container.getScrollX(), event.getRawY() + container.getScrollY()))){
					ChangeZoom(this.MODE_ZOOM);
				}
			}
			break;
		}

		case MotionEvent.ACTION_MOVE:
			if(!this.meuJogador.getMinhaClasse().equals("General")){
				currentX = (int) event.getRawX();
				currentY = (int) event.getRawY();
				currentX += container.getScrollX();
				currentY += container.getScrollY();
				
				meuJogador.sendPos(new PointF(currentX,currentY));
			}
			if(this.meuJogador.getMinhaClasse().equals("General")){
				int x2 = (int) event.getRawX();
				int y2 = (int) event.getRawY();
				switch (MODE_ZOOM) {
				case ZoomIN:
					meuJogador.dirViewPort(new Point(currentX,currentY), new Point(x2, y2), new Point(this.tamCanvasWidth, this.tamCanvasHeight), this.container, scale);
					currentX = x2;
					currentY = y2;					
					break;

				default:
					meuJogador.dirViewPort(new Point(currentX2,currentY2), new Point(x2, y2), new Point(this.tamCanvasWidth, this.tamCanvasHeight), this.container, scale);
					currentX2 = x2;
					currentY2 = y2;
					break;
				}
			}
			break;

		case MotionEvent.ACTION_UP:
			if(this.meuJogador.getMinhaClasse().equals("General")){
			this.meuJogador.setEndLocation(new PointF(currentX,currentY));
			this.meuJogador.setDrawTarget(true);
			Log.i("Log","aqui5");
			}
			break;

		case MotionEvent.ACTION_POINTER_2_DOWN:
			this.meuJogador.sendNewTiro(new Point(currentX,currentY));
			break;

		}
		return true;

	}
	private void ChangeZoom(Zoom zoom){
		switch (zoom) {
		case ZoomIN:
			valueContainer = new Point(container.getScrollX(), container.getScrollY());
			container.scrollTo(0, 0);
			scale = 0.7f;
			MODE_ZOOM = Zoom.ZoomOUT;
			break;

		default:
			scale = 1;
			container.scrollTo((this.meuJogador.getScrollX() + valueContainer.x),(this.meuJogador.getScrollY() + valueContainer.y));
			MODE_ZOOM = Zoom.ZoomIN;
			break;
		}
	}
	
	// ##### UPDATE #####
	private void update() {

	}

	// ##### DRAW #####
	public void draw(Canvas canvas) {
		super.draw(canvas);
		if(fontSize == 0){
			this.fontSize = (int)(30 * BitmapStorage.getInstance().getMunicao().getWidth()) / 100;
			this.paint.setTextSize(fontSize);
		}
		canvas.save();
		
		canvas.scale(scale, scale, 0, 0);
		
		this.tamCanvasWidth = (int)(this.canvasWidth * scale);
		this.tamCanvasHeight = (int)(this.canvasHeight * scale);
		
		canvas.drawBitmap(this.bg, 0, 0, null);
		
		ConcurrentHashMap<String, PlayerCliente> jogadores = clientManagerData
				.getJogadores();
		Iterator<String> iterator = jogadores.keySet().iterator();
	    
		while (iterator.hasNext()) {
			String key = iterator.next();
			PlayerCliente jogador = jogadores.get(key);
			jogador.draw(canvas);
			if(jogador.getNome().equals(this.meuJogador.getNome())){
				this.meuJogador.setPosition(jogador.getPosition());
				this.meuJogador.setMunicao(jogador.getMunicao());
				this.meuJogador.setBalas(jogador.getBalas());
				this.meuJogador.setDestinationTiro(jogador.getDestinationTiro());
			}
		}
		
		List<ItemCliente> itemList = clientManagerData.getItemList();
		for(ItemCliente item : itemList){
			item.draw(canvas);
		}
//		List<TiroCliente> tiroList = clientManagerData.getListTiros();
//		for(TiroCliente tiro : tiroList){
//			tiro.draw(canvas);
//		}
		canvas.restore();
		this.DrawInterface(canvas, this.meuJogador.getMinhaClasse());
	}
	public void DrawInterface(Canvas canvas, String classe){
		if(classe.equals("General")){
			if(this.lupa == null){
			this.lupa = new Lupa(new Point(canvas.getWidth(), canvas.getHeight()));
			}
			this.lupa.draw(canvas, container);
			canvas.drawBitmap(BitmapStorage.getInstance().getCaixote(), (canvas.getWidth() / 32) + this.container.getScrollX() , (canvas.getHeight() / 32) + this.container.getScrollY(), paint);
			canvas.drawBitmap(BitmapStorage.getInstance().getBandeira(), (canvas.getWidth() / 7) + this.container.getScrollX() , (canvas.getHeight() / 32) + this.container.getScrollY(), paint);
			canvas.drawBitmap(BitmapStorage.getInstance().getAviao(), (canvas.getWidth() / 3.95f) + this.container.getScrollX() , (canvas.getHeight() / 32) + this.container.getScrollY(), paint);
			canvas.drawBitmap(BitmapStorage.getInstance().getPointMobility(), (canvas.getWidth() / 2.75f) + this.container.getScrollX() , (canvas.getHeight() / 32) + this.container.getScrollY(), paint);
		}else if(classe.equals("Soldado")){
			canvas.drawBitmap(BitmapStorage.getInstance().getMunicao(), (canvas.getWidth() / 32) + this.container.getScrollX() , (canvas.getHeight() / 32) + this.container.getScrollY(), paint);
			canvas.drawText(""+this.meuJogador.getMunicao(), ((canvas.getWidth() / 11.5f) + this.container.getScrollX()), ((canvas.getHeight() / 6.75f) + this.container.getScrollY()), paint);
			canvas.drawText(""+this.meuJogador.getBalas(), ((canvas.getWidth() / 12) + this.container.getScrollX()), ((canvas.getHeight() / 10.5f) + this.container.getScrollY()), paint);
		}else if(classe.equals("Medico")){
			canvas.drawBitmap(BitmapStorage.getInstance().getMunicao(), (canvas.getWidth() / 32) + this.container.getScrollX() , (canvas.getHeight() / 32) + this.container.getScrollY(), paint);
			canvas.drawText(""+this.meuJogador.getMunicao(), ((canvas.getWidth() / 11.5f) + this.container.getScrollX()), ((canvas.getHeight() / 6.75f) + this.container.getScrollY()), paint);
			canvas.drawText(""+this.meuJogador.getBalas(), ((canvas.getWidth() / 12) + this.container.getScrollX()), ((canvas.getHeight() / 10.5f) + this.container.getScrollY()), paint);
		}
	}
	public void killMeSoftly() {
		ativo = false;
	}

}
